package org.jeecg.modules.paycenter.channel.bankdocking.service;

import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.paycenter.channel.bankdocking.dto.Acc;
import org.jeecg.modules.paycenter.enums.BillTypeEnum;
import org.jeecg.modules.paycenter.enums.PayChannelEnum;
import org.jeecg.modules.paycenter.enums.PaySourceEnum;
import org.jeecg.modules.paycenter.dto.PayBillData;
import org.jeecg.modules.paycenter.service.BasePayChannelService;
import org.jeecg.modules.paycenter.service.IPayChannelService;
import org.jeecg.modules.wlhy.bill.entity.HyBill;
import org.jeecg.modules.wlhy.bill.entity.HyCustomerBill;
import org.jeecg.modules.wlhy.bill.entity.HyShippingNoteBill;
import org.jeecg.modules.wlhy.company.entity.HyCompany;
import org.jeecg.modules.wlhy.customer.entity.HyCustomer;
import org.jeecg.modules.wlhy.customer.entity.HyCustomerAccountBook;
import org.jeecg.modules.wlhy.customer.entity.HyDfFee;
import org.jeecg.modules.wlhy.customer.service.IHyCustomerAccountBookService;
import org.jeecg.modules.wlhy.hycarrier.entity.HyCarrier;
import org.jeecg.modules.wlhy.hycarrier.entity.HyCarrierAccountBook;
import org.jeecg.modules.wlhy.hyconfig.entity.HyConfig;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriver;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriverAccountBook;
import org.jeecg.modules.wlhy.hyplatform.entity.HyPlatformAccountBook;
import org.jeecg.modules.wlhy.hyplatform.entity.HyPlatformCost;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicle;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingNote;
import org.jeecg.modules.wlhy.utils.HyConfigUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class NhPayChannelService extends BasePayChannelService implements IPayChannelService {

    @Autowired private NhBankService bankService;
    @Autowired private IHyCustomerAccountBookService hyCustomerAccountBookService;

    //region base
    @Override
    public PayChannelEnum getChannelEnum() {
        return PayChannelEnum.NH;
    }

    @Override
    public String getChannel() {
        return PayChannelEnum.NH.channelType;
    }

    @Override
    public boolean checkChannel() {
        HyConfig config = HyConfigUtils.getConfig();
        return config.getNhbankIzUse();
    }

    //endregion

    //region

    @Override
    public Result<?> batchDownloadCustomerBilHd(List<HyCustomerBill> customerBills){
        String channel = PayChannelEnum.NH.channelType;
        List<HyCustomerBill> failBills = new ArrayList<>();
        for (HyCustomerBill hyCustomerBill : customerBills) {
            try {
                if (!channel.equals(hyCustomerBill.getPayChannel())) {
                    continue;
                }
                if (!StringUtils.isEmpty(hyCustomerBill.getBankHdFu())) {
                    continue;
                }
                String filename = bankService.queryBankHd(hyCustomerBill.getPayDt(), hyCustomerBill.getDbProv(), hyCustomerBill.getDbaccno(),
                        hyCustomerBill.getBillNum(), hyCustomerBill.getAmt().negate());
                if(filename != null){
                    hyCustomerBill.setBankHdFu(filename);
                    hyCustomerBillService.updateById(hyCustomerBill);
                }
            }catch (Exception ex){
                failBills.add(hyCustomerBill);
                ex.printStackTrace();
            }
        }
        if(failBills.size() > 0) {
            return Result.OK(String.format("货主回单下载失败,失败条数为：",failBills.size()));
        }
        return Result.OK("货主回单下载成功");
    }

    @Override
    public Result<?> batchDownloadShippingBillHd(List<HyShippingNoteBill> shippingNoteBills){
        String channel = PayChannelEnum.NH.channelType;
        List<HyShippingNoteBill> failBills = new ArrayList<>();
        for (HyShippingNoteBill hyShippingNoteBill: shippingNoteBills) {
            try {
                if (!channel.equals(hyShippingNoteBill.getPayChannel())) {
                    continue;
                }
                if (hyShippingNoteBill.getBankHd() != null) {
                    continue;
                }
                String filename = bankService.queryBankHd(hyShippingNoteBill.getPayDt(), hyShippingNoteBill.getDbProv(), hyShippingNoteBill.getDbaccno(),
                        hyShippingNoteBill.getBillNum(), hyShippingNoteBill.getAmt().negate());
                if (filename != null) {
                    hyShippingNoteBill.setBankHd(filename);
                    hyShippingNoteBillService.updateById(hyShippingNoteBill);
                }
            } catch (Exception ex) {
                failBills.add(hyShippingNoteBill);
                ex.printStackTrace();
            }
        }
        if(failBills.size() > 0) {
            return Result.error(500,String.format("运单回单下载失败,失败条数为：",failBills.size()));
        }
        return Result.OK("运单回单下载成功");
    }
    //endregion


    //region ֧��

    @Override
    public Result<?> billPayBatch(List<HyBill> hyBills, HyCustomer customer) {
        HyCustomerAccountBook customerAccountBook = hyCustomerAccountBookService.getAccountBookByCustomerId(customer.getId());
        if (customerAccountBook == null) {
            return Result.error("货主账户异常!");
        }
        Acc customerAcc = hyCustomerAccountBookService.getCustomerAcc(customerAccountBook);
        if (customerAcc == null) {
            return Result.error("货主账号不存在");
        }
        BigDecimal totalAmt = billService.getBillCustomerTotalFee(hyBills);
        BigDecimal availBal = customerAcc.getAvailBal();
        if (totalAmt.compareTo(availBal) == 1) {
            return Result.error("余额不足请充值");
        }
        List<HyShippingNote> hyShippingNotes = billService.getBillShippingList(hyBills);
        Map<String, HyDriver> driverMaps = billService.getDriverMaps(hyShippingNotes);
        Map<String, HyVehicle> vehicleMaps = billService.getVehicleMaps(hyShippingNotes);
        Map<String, HyCarrier> carrierMaps = billService.getCarrierMaps(hyShippingNotes);

        Result<?> driverRet = bankService.getDriverAccounts(driverMaps);
        if (!driverRet.isSuccess()) {
            return driverRet;
        }

        Map<String, HyDriverAccountBook> driverAccountBookMaps = (Map<String, HyDriverAccountBook>) driverRet.getResult();
        Map<String, HyCarrierAccountBook> carrierAccountBookHashMaps = bankService.getCarrierAccounts(carrierMaps);
        Map<String, HyCompany> companyMaps = billService.getCompanyMaps();
        Map<String, HyShippingNote> shippingNoteMap = billService.shippingListToMap(hyShippingNotes);

        billService.checkBills(hyBills , shippingNoteMap);

        for (HyBill hyBill : hyBills) {
            hyBill.setPaySource(PaySourceEnum.ACCOUNT_PAY.value);
        }

        List<PayBillData> payDatas = billService.createBillPayDatas(this.getChannel(), hyBills, shippingNoteMap, driverMaps, vehicleMaps);

        bankService.setBillPayDatasAccInfo(payDatas, customerAccountBook, companyMaps, driverAccountBookMaps, carrierAccountBookHashMaps);
        billService.saveBillPayDatas(hyBills, payDatas);
        this.billPayBatch(hyBills);
        return Result.OK("交易发起成功");
    }

    @Override
    public Result<?> billPlateformPay(List<HyBill> hyBills, HyCustomer customer) {
        List<HyShippingNote> hyShippingNotes = billService.getBillShippingList(hyBills);
        Map<String, HyDriver> driverMaps = billService.getDriverMaps(hyShippingNotes);
        Map<String, HyVehicle> vehicleMaps = billService.getVehicleMaps(hyShippingNotes);
        Map<String, HyCarrier> carrierMaps = billService.getCarrierMaps(hyShippingNotes);

        Result<?> driverRet = bankService.getDriverAccounts(driverMaps);
        if (!driverRet.isSuccess()) {
            return driverRet;
        }
        Map<String, HyDriverAccountBook> driverAccountBookMaps = (Map<String, HyDriverAccountBook>) driverRet.getResult();
        Map<String, HyCarrierAccountBook> carrierAccountBookHashMaps = bankService.getCarrierAccounts(carrierMaps);


        BigDecimal totalAmt = billService.getBillCustomerTotalFee(hyBills);

        Result<?> ckinfo = bankService.checkPlatformAcc(totalAmt);
        if(!ckinfo.isSuccess()){
            return ckinfo;
        }
        HyPlatformAccountBook platformAccountBook = (HyPlatformAccountBook) ckinfo.getResult();
        Map<String, HyCompany> companyMaps = billService.getCompanyMaps();
        Map<String, HyShippingNote> shippingNoteMap = billService.shippingListToMap(hyShippingNotes);

        billService.checkBills(hyBills , shippingNoteMap);

        HyPlatformCost platformCost = new HyPlatformCost();
        platformCost.setCustomerId(customer.getId());
        platformCost.setCustomerBillNums(hyShippingNotes.size());
        platformCost.setSt("0");
        platformCost.setPayChannel(this.getChannel());
        platformCost.setAmt(totalAmt);
        if (!hyPlatformCostService.save(platformCost)) {
            throw new JeecgBootException("平台回单创建失败");
        }

        for (HyBill hyBill : hyBills) {
            hyBill.setPaySource(PaySourceEnum.PLATFORM_PAY.value);
            hyBill.setDfId(platformCost.getId());
        }
        List<PayBillData> payDatas = billService.createBillPayDatas(this.getChannel(), hyBills, shippingNoteMap, driverMaps, vehicleMaps);
        bankService.setBillPayDatasAccInfo(payDatas, platformAccountBook, companyMaps, driverAccountBookMaps, carrierAccountBookHashMaps);
        billService.saveBillPayDatas(hyBills, payDatas);
        this.billPayBatch(hyBills);
        return Result.OK("平台代付发起成功");
    }

    @Override
    public Result<?> billRePayBatch(List<HyBill> hyBills, HyCustomer customer) {
        List<PayBillData> payDatas = billService.getBillRePayDatas(hyBills);
        bankService.setBillRePayDatas(payDatas);
        this.billPayBatch(hyBills);
        return Result.OK("重新支付交易发起成功");
    }

    @Override
    public Result<?> agentDianFuPayBatch(BillTypeEnum billTypeEnum, List<HyBill> hyBills, HyCustomer agent, HyCustomer customer) {
        HyCustomerAccountBook agentAccountBook = hyCustomerAccountBookService.getAccountBookByCustomerId(agent.getId());
        if (agentAccountBook == null) {
            return Result.error("经纪人账户不存在!");
        }
        Acc customerAcc = hyCustomerAccountBookService.getCustomerAcc(agentAccountBook);
        if (customerAcc == null) {
            return Result.error("经纪人银行账户异常");
        }
        BigDecimal totalAmt = billService.getBillCustomerTotalFee(hyBills);
        BigDecimal availBal = customerAcc.getAvailBal();
        if (totalAmt.compareTo(availBal) == 1) {
            return Result.error("经纪人余额不足，请充值");
        }
        List<HyShippingNote> hyShippingNotes = billService.getBillShippingList(hyBills);
        Map<String, HyDriver> driverMaps = billService.getDriverMaps(hyShippingNotes);
        Map<String, HyVehicle> vehicleMaps = billService.getVehicleMaps(hyShippingNotes);
        Map<String, HyCarrier> carrierMaps = billService.getCarrierMaps(hyShippingNotes);

        Result<?> driverRet = bankService.getDriverAccounts(driverMaps);
        if (!driverRet.isSuccess()) {
            return driverRet;
        }

        Map<String, HyDriverAccountBook> driverAccountBookMaps = (Map<String, HyDriverAccountBook>) driverRet.getResult();
        Map<String, HyCarrierAccountBook> carrierAccountBookHashMaps = bankService.getCarrierAccounts(carrierMaps);
        Map<String, HyCompany> companyMaps = billService.getCompanyMaps();
        Map<String, HyShippingNote> shippingNoteMap = billService.shippingListToMap(hyShippingNotes);

        billService.checkBills(hyBills , shippingNoteMap);

        HyDfFee df = new HyDfFee();
        df.setBillType(billTypeEnum.value);
        df.setCustomerId(customer.getId());
        df.setAgentId(agent.getId());
        df.setBillNums(hyShippingNotes.size());
        df.setAmt(totalAmt);
        df.setSt("0");
        df.setPayChannel(this.getChannel());
        hyDfFeeService.save(df);
        for (HyBill hyBill : hyBills) {
            hyBill.setPaySource(PaySourceEnum.AGENT_PAY.value);
            hyBill.setDfId(df.getId());
        }
        List<PayBillData> payDatas = billService.createBillPayDatas(this.getChannel(), hyBills, shippingNoteMap, driverMaps, vehicleMaps);
        bankService.setBillPayDatasAccInfo(payDatas, agentAccountBook, companyMaps, driverAccountBookMaps, carrierAccountBookHashMaps);
        billService.saveBillPayDatas(hyBills, payDatas);
        this.billPayBatch(hyBills);
        return Result.OK("经纪人支付交易发起成功");
    }

    //endregion
}
